﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Collections;

namespace Acms.Bll
{
    public static class UserHelper 
    {
        public static string GetDepartment(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomString1;
            else
                return null;
        }

        public static void SetDepartment(this Acms.Bll.User user, string value)
        {
            if (user != null)
                user.CustomString1 = value;
        }
    
        public static int GetCountryId(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomInt1 == null ? 0 : user.CustomInt1.Value;
            else
                return 0;
        }

        public static void SetCountryId(this Acms.Bll.User user, int value)
        {
            if (user != null)
                user.CustomInt1 = value;
        }

        public static string GetState(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomString2;
            else
                return null;
        }

        public static void SetState(this Acms.Bll.User user, string value)
        {
            if (user != null)
                user.CustomString2 = value;
        }

        public static string GetComment(this Acms.Bll.User user)
        {
            if (user != null)
                return user.GetCustomProperty("Comment");
            else
                return null;
        }

        public static void SetComment(this Acms.Bll.User user, string value)
        {
            if (user != null)
                user.SetCustomProperty("Comment", value);
        }

        public static bool GetAnon(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomBool1 ?? false;
            else
                return false;
        }

        public static void SetAnon(this Acms.Bll.User user, bool value)
        {
            if (user != null)
                user.CustomBool1 = value;
        }

        public static bool GetRelative(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomBool2 ?? false;
            else
                return false;
        }

        public static void SetRelative(this Acms.Bll.User user, bool value)
        {
            if (user != null)
                user.CustomBool2 = value;
        }

        public static int? GetThumbnailId(this Acms.Bll.User user)
        {
            if (user != null)
                return user.CustomInt2;
            else
                return null;
        }

        public static void SetThumbnailId(this Acms.Bll.User user, int? value)
        {
            if (user != null)
                user.CustomInt2 = value;
        }

        public static string EmailValidationExpression = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z+])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";
        public static string PasswordFormatErrorMessage = "Password must start with a letter and be between 5 and 14 characters. No spaces are allowed.";
        public static string PasswordValidationExpression = @"^[a-zA-Z][\S]{4,13}$";
        
/*        public static string EmailValidationExpression = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z+])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$";
        public static string PasswordFormatErrorMessage = "Password must start with a letter and be between 5 and 14 characters. No spaces are allowed.";
        public static string PasswordValidationExpression = @"^[a-zA-Z][\S]{4,13}$";

        public int Id { get; internal set; }
        public int? SiteId { get; internal set; }
        public string EmailAddress { get; set; }
        public string EncodedPassword { get; internal set; }
        public int Salt { get; internal set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Department { get; set; }
        public int CountryId { get; set; }
        public string State { get; set; }
        public string Comment { get; set; }
        public int ThumnailId { get; set; }
        public bool Anon { get; set; }
        public bool Relative { get; set; }
        public bool EmailAuthenticated { get; internal set; }
        public DateTime Created { get; internal set; }

        internal LinqUtilities.LazyItem<Country, Dal.Country> _Country;
        public Country Country
        {
            get { return _Country.Item; }
            set { _Country.Item = value; if (value != null) this.CountryId = value.Id; }
        }

        public string DisplayName
        {
            get
            {
                var tmp = string.Concat(FirstName, " ", LastName);
                tmp = tmp.Trim().Replace("  ", " ");
                return tmp;
            }
        }

        private void CreateSalt()
        {
            Byte[] _saltBytes = new Byte[4];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(_saltBytes);

            Salt = ((((int)_saltBytes[0]) << 24) + (((int)_saltBytes[1]) << 16) + (((int)_saltBytes[2]) << 8) + ((int)_saltBytes[3]));
        }

        //used to hold password for emailing
        private string tmpNewPassword;
        public bool SetPassword(string originalPassword, string newPassword)
        {
            bool retVal = false;
            if (!string.IsNullOrEmpty(EncodedPassword) && string.IsNullOrEmpty(originalPassword))
            {
                throw new ApplicationException("Original password must be supplied if password already set.");
            }
            if (!System.Text.RegularExpressions.Regex.Match(newPassword, User.PasswordValidationExpression).Success)
            {
                throw new Exceptions.ValidationExceptionItem(User.PasswordFormatErrorMessage);
            }
            if (string.IsNullOrEmpty(EncodedPassword) || (AuthenticatePassword(originalPassword) && !AuthenticatePassword(newPassword)))
            {
                CreateSalt();
                EncodedPassword = ComputeSaltedHash(newPassword);
                retVal = true;
            }
            tmpNewPassword = newPassword;
            return retVal;
        }

        public bool AuthenticatePassword(string password)
        {
            string tmp = ComputeSaltedHash(password);
            return tmp == this.EncodedPassword;
        }

        private string ComputeSaltedHash(string password)
        {
            // Create Byte array of password string
            ASCIIEncoding encoder = new ASCIIEncoding();
            Byte[] secretBytes = encoder.GetBytes(password);

            // Create a new salt
            Byte[] saltBytes = new Byte[4];
            saltBytes[0] = (byte)(Salt >> 24);
            saltBytes[1] = (byte)(Salt >> 16);
            saltBytes[2] = (byte)(Salt >> 8);
            saltBytes[3] = (byte)(Salt);

            // append the two arrays
            Byte[] toHash = new Byte[secretBytes.Length + saltBytes.Length];
            Array.Copy(secretBytes, 0, toHash, 0, secretBytes.Length);
            Array.Copy(saltBytes, 0, toHash, secretBytes.Length, saltBytes.Length);

            SHA1 sha1 = SHA1.Create();
            Byte[] computedHash = sha1.ComputeHash(toHash);

            return encoder.GetString(computedHash);
        }
*/
    }
}
